import { Example } from '../../components'
import { Link } from '@brillout/docpress'

<a href="https://github.com/vercel/styled-jsx">`styled-jsx`</a> is a <Link href="/css-in-js" text="CSS in JS" /> tool that is supported by default in Next.js.
Next.js manages server side hydration of styles as well as transpilation, so to work with Vite we'll need to do this manually.

Example:
 - <Example timestamp="2023.07" repo="jeremypress/vite-ssr-styled-jsx" />
   > vite-plugin-ssr was the [previous name of Vike](https://vite-plugin-ssr.com/vike).

To use Vike with `styled-jsx`:

1. Install:

```shell
npm install styled-jsx
```

2. Add `styled-jsx` to `vite.config.js`:

```js
// vite.config.js

import react from '@vitejs/plugin-react'
import vike from 'vike/plugin'

export default {
  plugins: [react({ babel: { plugins: ['styled-jsx/babel'] } }), vike()]
}
```

3. Collect the styles during server-side rendering and attach to the DOM as `<head>` tags.

```js
// /renderer/+onRenderHtml.js

export { onRenderHtml }

import React from 'react'
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
import { escapeInject, dangerouslySkipEscape } from 'vike/server'
import { Layout } from './Layout'
import { createStyleRegistry, StyleRegistry } from 'styled-jsx'

const registry = createStyleRegistry()

async function onRenderHtml(pageContext) {
  // flush styles to support the possibility of concurrent rendering
  registry.flush()

  const { Page } = pageContext
  // include the styleregistry in the app render to inject the styles
  const viewHtml = dangerouslySkipEscape(
    renderToString(
      <StyleRegistry registry={registry}>
        <Layout>
          <Page />
        </Layout>
      </StyleRegistry>
    )
  )

  // extract the styles to add as head tags to the server markup
  const headTags = renderToStaticMarkup(<>{registry.styles()}</>)

  return escapeInject`<!DOCTYPE html>
    <html>
      <head>
        ${dangerouslySkipEscape(headTags)}
      </head>
      <body>
        <div id="page-view">${viewHtml}</div>
      </body>
    </html>`
}
```
